package com.ledim.chat;

import com.ledim.chat.model.MessageHeader;

public class ByteArrayBuilder {

    private int mCount = 0;
    private byte[] mBuf = null;

    public ByteArrayBuilder() {
        mBuf = new byte[MessageHeader.LENGTH];
    }

    public ByteArrayBuilder(int len) {
        mBuf = new byte[len];
    }

    void expandCapacity(int minimumCapacity) {
        int newCapacity = (mBuf.length + 1) * 2;
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
            newCapacity = minimumCapacity;
        }
        byte newBuff[] = new byte[newCapacity];
        System.arraycopy(mBuf, 0, newBuff, 0, mCount);
        mBuf = newBuff;
    }

    /**
     * 32位
     *
     * @param i
     * @return
     */
    public ByteArrayBuilder writeUint32(int i) {
        int newcount = mCount + 4;
        if (newcount > mBuf.length) {
            expandCapacity(newcount);
        }
        mBuf[mCount + 3] = (byte) (i & 0x000000FF);
        mBuf[mCount + 2] = (byte) ((i & 0x0000FF00) >> 8);
        mBuf[mCount + 1] = (byte) ((i & 0x00FF0000) >> 16);
        mBuf[mCount] = (byte) ((i & 0xFF000000) >> 24);
        mCount = newcount;
        return this;
    }

    /**
     * 16位
     *
     * @param i
     * @return
     */
    public ByteArrayBuilder writeUint16(int i) {
        int newcount = mCount + 2;
        if (newcount > mBuf.length) {
            expandCapacity(newcount);
        }
        mBuf[mCount + 1] = (byte) (i & 0x000000FF);
        mBuf[mCount] = (byte) ((i & 0x0000FF00) >> 8);
        mCount = newcount;
        return this;
    }

    public ByteArrayBuilder write(byte[] b, int off, int len) {
        if (b == null) {
            return this;
        }
        if ((off < 0) || (off > b.length) || (len < 0) ||
                ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return this;
        }
        int newcount = mCount + len;
        if (newcount > mBuf.length) {
            expandCapacity(newcount);
        }
        System.arraycopy(b, off, mBuf, mCount, len);
        mCount = newcount;
        return this;
    }

    public ByteArrayBuilder write(byte[] b) {
        if (b == null) {
            return this;
        }
        return write(b, 0, b.length);
    }

    public byte[] toBytes() {
        if (mCount == mBuf.length) {
            return mBuf;
        }
        byte[] newbuff = new byte[mCount];
        System.arraycopy(mBuf, 0, newbuff, 0, mCount);
        return newbuff;
    }
}
